from config import config
from tools import logger,thread
import ConfigParser
import os
import datetime
import json
import signal
import time
import sys
from time import sleep
import commands
#global init_tasks
#global waitTime
#global next_instantiationFlag
next_instantiationFlag=False
waitTime=config.waittime
init_tasks={}
workpath=os.getcwd()
today=str(datetime.date.today())
logger=logger.Logger(__name__,workpath+'/log/main.log').getLogger()
#loggerErr=logger.Logger(__name__,workpath+'/log/err.log').getLogger()
def getToday():
    return str(datetime.date.today())
def get_next_date():
    today= datetime.date.today()
    return str(today + datetime.timedelta(days=1))
def get_next_next_date():
    today= datetime.date.today()
    return str(today + datetime.timedelta(days=2))
def readConfig():
    tasks={}
    readconfig=ConfigParser.ConfigParser()
    readconfig.read(workpath+'/tasks/tasks.ini')
    sections=readconfig.sections()
    for section in sections:
        tasks[section]=readconfig.items(section)
    return tasks
def writeConfig(tasks,next_day):
    logger.info('next_day=[%s]' % next_day)
    try:
        for key in tasks.keys():
            logger.info(tasks[key])
            if ('isexecute','ON') in  tasks[key]:
                writeconfig=ConfigParser.ConfigParser()
                writeconfig.add_section(key)
                for v in tasks[key]:
                    writeconfig.set(key,v[0],v[1])
                writeconfig.set(key,'rundate',next_day)
                writeconfig.set(key,'enddate',get_next_next_date())
                writeconfig.set(key,'status','init')
                filename=workpath+'/tasks/'+next_day+'_'+key+'_task.ini'
                logger.info("instantiation-->"+filename)
                with open(filename,'w') as f:
                    writeconfig.write(f)
            else:
                logger.info('task=[%s],isexecute=[%s]' % (key,'OFF'))
    except Exception as e:
        logger.error('error:[%s]' % repr(e))
def next_task_instantiation():
    try:
        next_day=get_next_date()
        tasks=init_tasks
        if not tasks:
            raise OSError
        logger.info('tasks=[%s]' % json.dumps(tasks))
        writeConfig(tasks,next_day)
        with open(workpath+'/nextworkDate','w') as wf:
            wf.write(next_day)
        return next_day
    except OSError:
        logger.error("Can't open config file: tasks.ini")
        return None
def getTodayTasks():
    #read init tasks.ini
    tasks=init_tasks
    task={}
    today=getToday()
    todayTasks={}
    for key in tasks.keys():
        TaskFile=workpath+'/tasks/'+today+'_'+key+'_task.ini'
        if not os.path.exists(TaskFile):
            logger.error("Taskfile=[%s] is not exists."% TaskFile )
            if ('isexecute','ON') in  tasks[key]:
                tmp=list(tasks[key])
                tmp.append(('init','tasks.ini'))
                tmp.append(('rundate',today))
                tmp.append(('enddate',get_next_date()))
                tmp.append(('status','init'))
                todayTasks[key]=listTodict(tmp)
            else:
                logger.info('task=[%s],isexecute=[%s]' % (key,'OFF'))
            
        else:
            logger.info("Taskfile=[%s] is exists."% TaskFile)
            readconfig=ConfigParser.ConfigParser()
            readconfig.read(TaskFile)
            sections=readconfig.sections()
            for section in sections:
                task[section]=readconfig.items(section)
            if ('isexecute','ON') in  task[key]:
                tmp=list(task[key])
                todayTasks[key]=listTodict(tmp)
            else:
                logger.info('task=[%s],isexecute=[%s]' % (key,'OFF'))
    return todayTasks
def listTodict(listdate):
    task_dict={}
    for i in listdate:
        task_dict[i[0]]=i[1]
    return task_dict
def kill(pid):
    import signal
    pname=os.popen('ps -ef| grep %s | grep -v grep' % pid)
    logger.info("kill pid:[%s]" % pname.readlines())
    try:
        
        os.kill(int(pid),signal.SIGKILL)
        logger.info("killed pid=[%s] finished." % pid )
        return 0
    except Exception as e:
        logger.error('error:[%s]' % repr(e))
        return 1
def getOldTaskPids():
    TaskPids={}
    fileslist=os.listdir(workpath+'/pid')
    pid=''
    for f in fileslist:
        tmpPath=workpath+'/pid/'+f
        pid= os.popen('cat %s' % tmpPath)
        appCode=f.split('.')[0]
        TaskPids[appCode]=pid.readlines()[0]
    logger.info('TaskPids=[%s]' % json.dumps(TaskPids))
    return TaskPids
def getOldTaskPid(task):
    filesname=workpath+'/pid/'+task+'.pid'
    if os.path.exists(filesname):
        pid= os.popen('cat %s' % filesname)
        TaskPid=pid.readlines()[0]
        logger.info('Task=[%s],TaskPid=[%s]' % (task,TaskPid))
        return TaskPid
    else:
        return None
def initTasks():
    global init_tasks
    init_tasks=readConfig()
    today=getToday()
    with open(workpath+'/'+config.workDatePath,'w') as f:
        f.write(today)
    with open(workpath+'/'+config.nextworkDatePath,'w') as f:
        f.write(get_next_date()) 
    logger.info("initTasks=[%s]" % json.dumps(init_tasks))
    todayTasks=getTodayTasks()
    logger.info("todayTask=[%s]" % json.dumps(todayTasks))
    oldTaskPids=getOldTaskPids()
    logger.info('oldTaskPids=[%s]' % json.dumps(oldTaskPids))
    return init_tasks,todayTasks,oldTaskPids
def getTimeSec():
    ct=time.time()
    return int(ct)
def strToSec(strtime):
    timeArray=time.strptime(strtime,'%Y-%m-%d %H:%M:%S')
    return int(time.mktime(timeArray))
def getStrTime(Sec):
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(Sec))
def execcmd(argv):
    logger.info('python %s %s' % (workpath+config.callfunc,' '.join(argv)))
    execcmd_ret=os.system('python %s %s' % (workpath+config.callfunc,' '.join(argv)))
    logger.info('execcmd_ret=[%d]' % (execcmd_ret >> 8))
def getTaskStatus(task):
    status='init'
    taskStatusPath=workpath+'/taskStatus/'+task+'.status'
    try:
        with open(taskStatusPath,'r') as f:
            status = f.readline()
    except Exception as e:
        logger.error('error:[%s]' % repr(e))
        logger.info('set up %s' % taskStatusPath )
        with open(taskStatusPath,'w') as f:
            f.write('init')
    return status
def initTaskStatus(tasks):
    status='init'
    taskStatusPath=workpath+'/taskStatus/'
    for key in tasks.keys():
        #ret,oldStatus=commands.getstatusoutput("cat %s" % taskStatusPath+key+'.status')
        with open(taskStatusPath + key +'.status','w') as w:
            w.write(status)
def initCBS():
    try:
        userPath= os.path.expanduser('~')
        CBSFilename= userPath + '/etc/fcbclient.pid'
        if os.path.exists(CBSFilename): 
           ret,oldPid=commands.getstatusoutput('cat %s' % CBSFilename)
           ret = kill(oldPid)
           if ret == 1:
              logger.warn('killed error pid=[%s]' % oldPid )
           logger.info('init FCB1S91500VAR.ini')
           if os.path.exists(userPath+'/etc/FCB1S91500VAR.ini'):
              if os.path.getsize(userPath+'/etc/FCB1S91500VAR.ini') > 0:
                 os.remove(userPath+'/etc/FCB1S91500VAR.ini')
                 os.mknod(userPath+'/etc/FCB1S91500VAR.ini')
                 logger.info('init FCB1S91500VAR.ini finished.')
              else:
                  logger.info('file=[%s],size=[0]' %(userPath+'/etc/FCB1S91500VAR.ini'))
           else:
               os.mknod(userPath+'/etc/FCB1S91500VAR.ini')
               logger.warn('file=[%s] is not  exists!' % (userPath+'/etc/FCB1S91500VAR.ini'))
        else:
            logger.warn('CBSFilename=[%s] is not exists!' % CBSFilename )
    except Exception as e:
        logger.error('error:[%s]' % repr(e))
    
def main():
    global next_instantiationFlag
    with open(workpath+'/cronMain.pid','w') as f:
        f.write(str(os.getpid()))
    nextworkDatePath=workpath+'/'+config.nextworkDatePath
    nowworkDatePath=workpath+'/'+config.workDatePath
    logger.info('init task')
    init_tasks,todayTasks,oldTaskPids=initTasks()
    initTaskStatus(init_tasks)
    while True:
        nowSec=getTimeSec()
        instantiationTime=getToday()+ ' ' + config.instantiationTime
        logger.info("nowSec=[%d],nowTime=[%s]" %(nowSec,getStrTime(nowSec)))
        if strToSec(instantiationTime) <= nowSec :
            if not next_instantiationFlag:
                logger.info('nowTime=[%s] > instantiationTime=[%s],start next_task_instantiation()' %(getStrTime(nowSec),instantiationTime))
                init_day=next_task_instantiation()
                
                next_instantiationFlag=True
                logger.info("instantiation after,next_day=[%s] " % init_day)
            else:
                logger.info('instantiation finished,next_instantiationFlag=[%s]' % str(next_instantiationFlag))
        else:
            logger.info("instantiation Time is not yet available.")
        nextworkDate=os.popen('cat %s' % nextworkDatePath).readlines()
        if strToSec(nextworkDate[0]+' '+ '00:00:00') <= nowSec:
            with open(nowworkDatePath,'w') as f:
                f.write(nextworkDate[0])
            with open(nextworkDatePath,'w') as w:
                w.write(get_next_date())
            logger.info('nowwork=[%s],nextwork=[%s],init tasks'%(nextworkDate,get_next_date()))
            init_tasks,todayTasks,oldTaskPids=initTasks() 
            initTaskStatus(init_tasks)
            
            next_instantiationFlag=False
            logger.info("init  next_instantiationFlag=[%s] " % str(next_instantiationFlag))
        for key in todayTasks.keys():
            runtime= todayTasks[key].get('rundate')+' '+todayTasks[key].get('runtime')
            runSec=strToSec(runtime)
            logger.info('task:[%s],runtime=[%s],runSec=[%d]' % (key,runtime,runSec))
            if runSec <= nowSec:
                taskStatus=getTaskStatus(key)
                todayTasks[key]['status']=taskStatus
                logger.info('task=[%s],status=[%s]' %(key,taskStatus))
                if todayTasks[key].get('status') in ['running','finished'] :
                    logger.info('task:[%s],is running or finished.' % key)
                    continue
                else:
                    #oldtaskpid=oldTaskPids.get(key)
                    if key == 'CBS':
                       initCBS()
                    oldtaskpid=getOldTaskPid(key)
                    if oldtaskpid:
                        ret=kill(oldtaskpid)
                        if ret == 1:
                            logger.warn('killed error pid=[%s]' % oldtaskpid )
                        else:
                            logger.info('killed success! pid=[%s]' % oldtaskpid)
                    else:
                        logger.warn('oldtaskpid=[%s]' % oldtaskpid)
                logger.info('task:[%s],start up' % key)
                #sys.exit(0)
                try:
                    
                    th=thread.Thread(key,todayTasks[key]['calltype'],workpath,todayTasks[key].get('filename'),todayTasks[key].get('max_num'),
                                     func=execcmd,logger=logger,taskID=key)
                    th.start()
                    todayTasks[key]['status']='running'
                except Exception as e:
                    logger.error('error:[%s]' % repr(e))
            else:
                logger.info('task:[%s],time is not yet available.' % key)
        logger.info('waitTime=[%d]' % waitTime)
        sleep(waitTime)
if __name__ == '__main__':
    mainPath=os.getcwd()+ '/cronMain.pid'
    with open(mainPath,'r') as f:
        mainPid=f.readline()
    is_Pid_exist=os.popen('ps -ef| grep %s | grep -v grep' % mainPid).readlines()
    if mainPid and is_Pid_exist:
        #logger.error('cronMain=[%s],process=[%s]' %(mainPid,is_Pid_exist))
        #logger.error("cronMain is running.not allow start-up!") 
        print 'cronMain=[%s],process=[%s]' %(mainPid,is_Pid_exist)
        print "cronMain is running.not allow start-up!"
        sys.exit(1)
    else:
        logger.info("cronMain is not running.allow start-up.")
        main()
